/**
 * Copyright (c) 2011 Daniel Centore
 *
 * ex: set filetype=java expandtab tabstop=4 shiftwidth=4 :
 * 
 * This program is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 *
 * This code is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * This code is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation.
 */
package wiiWired.controller.mote.buttons;

import motej.event.CoreButtonEvent;
import motejx.extensions.nunchuk.NunchukButtonEvent;

/**
 * Transparently handles buttons of the Nunchuk and WiiRemote
 * Usage: Create new ButtonController and pipe buttonPressed(..) calls into it
 * 
 * @author Daniel Centore
 *
 */
public class ButtonController {
	
	private boolean[] oldPressed;	//buttons that were pressed at last check (for comparison)
	private boolean[] pressed;		//buttons that are currently pressed
	private ButtonListener listener;	//the listener we are going to send info to!
	
	/**
	 * Initializes a ButtonController. Pump button events into it.
	 * @param l The listener we send the transparent handling to
	 */
	public ButtonController(ButtonListener l)
	{
		listener = l;
		
		pressed = new boolean[Button.LAST_BUTTON+1];
		oldPressed = new boolean[pressed.length];
	}
	
	/**
	 * A button was pressed on the WiiMote
	 * @param arg0
	 */
	public void buttonPressed(CoreButtonEvent arg0)
	{
		handlePressed(Button.DPAD_UP,    arg0.isDPadUpPressed());
		handlePressed(Button.DPAD_DOWN,  arg0.isDPadDownPressed());
		handlePressed(Button.DPAD_LEFT,  arg0.isDPadLeftPressed());
		handlePressed(Button.DPAD_RIGHT, arg0.isDPadRightPressed());
		
		handlePressed(Button.A_BUTTON, arg0.isButtonAPressed());
		handlePressed(Button.B_BUTTON, arg0.isButtonBPressed());
		
		handlePressed(Button.MINUS_BUTTON, arg0.isButtonMinusPressed());
		handlePressed(Button.HOME_BUTTON,  arg0.isButtonHomePressed());
		handlePressed(Button.PLUS_BUTTON,  arg0.isButtonPlusPressed());
		
		handlePressed(Button.ONE_BUTTON, arg0.isButtonOnePressed());
		handlePressed(Button.TWO_BUTTON, arg0.isButtonTwoPressed());
		
		doDifference();
	}
	
	/**
	 * A button was pressed on the nunchuk
	 * @param arg0
	 */
	public void buttonPressed(NunchukButtonEvent arg0)
	{
		handlePressed(Button.C_BUTTON,  arg0.isButtonCPressed());
		handlePressed(Button.Z_TRIGGER, arg0.isButtonZPressed());
		
		doDifference();
	}
	
	/**
	 * Updates the array based on whether or not it is pressed
	 * @param button
	 * @param b
	 */
	private synchronized void handlePressed(int button, boolean b)
	{
		pressed[button] = b;
	}
	
	/**
	 * Checks for differences to the pressed arrays,
	 *   calls listener methods as needed, and sets oldPressed to a clone of pressed
	 */
	private synchronized void doDifference()
	{
		for(int i = 0; i < oldPressed.length; i++)
		{
			if(oldPressed[i] != pressed[i])
			{
				if(pressed[i])
					listener.buttonPressed(i);
				else
					listener.buttonReleased(i);
			}
		}
		
		for(int i = 0; i < pressed.length; i++)		//copy over
			oldPressed[i] = pressed[i];
	}

}
